#include "StdAfx.h"
#include "SysRender.h"

CSysRender::CSysRender(void):m_pRoot(NULL),mWindow(NULL)
{

}

CSysRender::~CSysRender(void)
{

}

void CSysRender::Init(HWND hWnd)
{
	m_hAttach = hWnd;
	setup();
}

void CSysRender::Render()
{
	mWindow->update(true);
}

void CSysRender::Deinit()
{
	if(m_pRoot)
	{
		delete m_pRoot;
		m_pRoot = NULL;
	}
}

void CSysRender::Resize(int x,int y,int lx,int ly)
{
	// notify "render window" instance
	mWindow->windowMovedOrResized();

	// Adjust camera's aspect ratio, too
	if (ly != 0 && NULL != mCamera)
		mCamera->setAspectRatio((Ogre::Real)lx / (Ogre::Real) ly);
}

// These internal methods package up the stages in the startup process
/** Sets up the application - returns false if the user chooses to abandon configuration. */
bool CSysRender::setup(void)
{

	String pluginsPath;
	// only use plugins.cfg if not static
#ifndef OGRE_STATIC_LIB
	pluginsPath = mResourcePath + "plugins.cfg";
#endif

	m_pRoot = new Root(pluginsPath, 
		mResourcePath + "ogre.cfg", mResourcePath + "Ogre.log");

	setupResources();

	bool carryOn = configure();
	if (!carryOn) return false;
	createWindow("this needs redesign",m_hAttach);

	chooseSceneManager();
	createCamera();
	createViewports();

	// Set default mipmap level (NB some APIs ignore this)
	TextureManager::getSingleton().setDefaultNumMipmaps(5);

	// Create any resource listeners (for loading screens)
	createResourceListener();
	// Load resources
	loadResources();

	// Create the scene
	createScene();

	createFrameListener();

	return true;
}


/** Configures the application - returns false if the user chooses to abandon configuration. */
bool CSysRender::configure(void)
{
	// Show the configuration dialog and initialise the system
	// You can skip this and use root.restoreConfig() to load configuration
	// settings if you were sure there are valid ones saved in ogre.cfg
	if(m_pRoot->showConfigDialog())
	{
		// If returned true, user clicked OK so initialise
		// Here we choose to let the system create a default rendering window by passing 'true'
		mWindow = m_pRoot->initialise(false);
		return true;
	}
	else
	{
		return false;
	}
}

void CSysRender::createWindow(const char* p,HWND hWnd )
{
	Ogre::NameValuePairList Properties;
	Properties.insert(
		Ogre::NameValuePairList::value_type("externalWindowHandle",
		Ogre::StringConverter::toString((long)hWnd)));
	
	CRect rectClient;
	::GetClientRect(hWnd,&rectClient);

	if(mWindow == NULL)
	{
		mWindow = m_pRoot->createRenderWindow("renderwin",
			rectClient.Width(), rectClient.Height(), false, &Properties);
		mWindow->setActive(true);
	}
	else
	{
		RayAssert(false);
	}
}

void CSysRender::chooseSceneManager(void)
{
	// Create the SceneManager, in this case a generic one
	mSceneMgr = m_pRoot->createSceneManager(ST_GENERIC, "ExampleSMInstance");
}
void CSysRender::createCamera(void)
{
	// Create the camera
	mCamera = mSceneMgr->createCamera("PlayerCam");

	// Position it at 500 in Z direction
	mCamera->setPosition(Vector3(0,0,500));
	// Look back along -Z
	mCamera->lookAt(Vector3(0,0,-300));
	mCamera->setNearClipDistance(5);

}
void CSysRender::createFrameListener(void)
{
	//mFrameListener= new ExampleFrameListener(mWindow, mCamera);
	//mFrameListener->showDebugOverlay(true);
	//m_pRoot->addFrameListener(mFrameListener);
}

void CSysRender::createViewports(void)
{
	RayAssert(mWindow != NULL);
	// Create one viewport, entire window
	Viewport* vp = mWindow->addViewport(mCamera);
	vp->setBackgroundColour(ColourValue(0,0,0));

	// Alter the camera aspect ratio to match the viewport
	mCamera->setAspectRatio(
		Real(vp->getActualWidth()) / Real(vp->getActualHeight()));
}

/// Method which will define the source of resources (other than current folder)
void CSysRender::setupResources(void)
{
	// Load resource paths from config file
	ConfigFile cf;
	cf.load(mResourcePath + "resources.cfg");

	// Go through all sections & settings in the file
	ConfigFile::SectionIterator seci = cf.getSectionIterator();

	String secName, typeName, archName;
	while (seci.hasMoreElements())
	{
		secName = seci.peekNextKey();
		ConfigFile::SettingsMultiMap *settings = seci.getNext();
		ConfigFile::SettingsMultiMap::iterator i;
		for (i = settings->begin(); i != settings->end(); ++i)
		{
			typeName = i->first;
			archName = i->second;
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
			// OS X does not set the working directory relative to the app,
			// In order to make things portable on OS X we need to provide
			// the loading with it's own bundle path location
			ResourceGroupManager::getSingleton().addResourceLocation(
				String(macBundlePath() + "/" + archName), typeName, secName);
#else
			ResourceGroupManager::getSingleton().addResourceLocation(
				archName, typeName, secName);
#endif
		}
	}
}

/// Optional override method where you can create resource listeners (e.g. for loading screens)
void CSysRender::createResourceListener(void)
{

}

/// Optional override method where you can perform resource group loading
/// Must at least do ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
void CSysRender::loadResources(void)
{
	// Initialise, parse scripts etc
	ResourceGroupManager::getSingleton().initialiseAllResourceGroups();

}
